package com.apps.saspect.impl;

import com.apps.shelper.AnnotationHelper;
import com.apps.shelper.ValidationHepler;
import com.apps.sannotation.constraints.*;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

@Slf4j
@Aspect
@Component
@Configuration
public class ValidMethodAspect {


    @Pointcut("@annotation(com.apps.saspect.ValidMethod)")
    public void pointcut() {

    }

    /**
     * 方法进入之前  注解传参为key,userid  其中,是+号,userid是方法参数名key是key的前缀
     * @param joinPoint
     */
    @Before("pointcut()")
    public void doBefore(JoinPoint joinPoint) {
        Object[] objects=joinPoint.getArgs();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Parameter[] parameter=method.getParameters();
        for(int i=0;i<parameter.length;i++){
            String fieldName=signature.getParameterNames()[i];
            Parameter item=parameter[i];
            Object obj=objects[i];
            try {
                //非空验证
                NoNull notNull = item.getAnnotation(NoNull.class);
                if (null != notNull)
                    ValidationHepler.validNoNullAnnotation(fieldName, obj, notNull);
                //字符串长度验证
                StrLen len = item.getAnnotation(StrLen.class);
                if (null != len)
                    ValidationHepler.validStrLenAnnotation(fieldName, obj, len);
                //字符串范围验证
                StrRange strRange = item.getAnnotation(StrRange.class);
                if (null != strRange)
                    ValidationHepler.validStrRangeAnnotation(fieldName, obj, strRange);
                //字符串最小验证
                StrMinLen strMinLen = item.getAnnotation(StrMinLen.class);
                if (null != strMinLen)
                    ValidationHepler.validStrMinLenAnnotation(fieldName, obj, strMinLen);
                //字符串最大验证
                StrMaxLen strMaxLen = item.getAnnotation(StrMaxLen.class);
                if (null != strMaxLen)
                    ValidationHepler.validStrMaxLenAnnotation(fieldName, obj, strMaxLen);
                //字符串必须是数字验证
                StrIsNumber strIsNumber = item.getAnnotation(StrIsNumber.class);
                if (null != strIsNumber)
                    ValidationHepler.validStrIsNumberAnnotation(fieldName, obj, strIsNumber);
                //手机号验证
                Mobile mobile = item.getAnnotation(Mobile.class);
                if (null != mobile)
                    ValidationHepler.validMobileAnnotation(fieldName, obj, mobile);
                //邮箱验证
                Email email = item.getAnnotation(Email.class);
                if (null != email)
                    ValidationHepler.validEmailAnnotation(fieldName, obj, email);
                //数字范围验证
                NumRange range = item.getAnnotation(NumRange.class);
                if (null != range)
                    ValidationHepler.validNumRangeAnnotation(fieldName, obj, range);
                //数字最小验证
                NumMin numMin = item.getAnnotation(NumMin.class);
                if (null != numMin)
                    ValidationHepler.validNumMinAnnotation(fieldName, obj, numMin);
                //数字最大验证
                NumMax numMax = item.getAnnotation(NumMax.class);
                if (null != numMax)
                    ValidationHepler.validNumMaxAnnotation(fieldName, obj, numMax);
                //小数点最大位数验证
                DecimalMaxLen decimalMaxLen = item.getAnnotation(DecimalMaxLen.class);
                if (null != decimalMaxLen)
                    ValidationHepler.validDecimalMaxLenAnnotation(fieldName, obj, decimalMaxLen);
                //正则匹配验证
                StrPattern strPattern = item.getAnnotation(StrPattern.class);
                if (null != strPattern)
                    ValidationHepler.validStrPattenAnnotation(fieldName, obj, strPattern);
                //数字范围验证
                NumLimits numLimits = item.getAnnotation(NumLimits.class);
                if (null != numLimits)
                    ValidationHepler.validNumLimitsAnnotation(fieldName, obj, numLimits);
                //对模型属性进行验证
                Prop prop = parameter[i].getAnnotation(Prop.class);
                if (null != prop) {
                    //再验证对象的所有属性
                    AnnotationHelper.verifyModelFiled(objects[i]);
                }
            }catch (Exception e)
            {
                log.error("class="+joinPoint.getTarget().getClass().getSimpleName()+":method="+method.getName());
                e.printStackTrace();
                throw  e;
            }
        }

    }


}
